﻿using System.IO;
using System.Threading;

namespace System
{
    public static class Log
    {
        public const ConsoleColor DefaultColor = ConsoleColor.Gray;

        public static TextWriter Debug { get; set; }
        public static TextWriter Information { get; set; }
        public static TextWriter Warning { get; set; }
        public static TextWriter Error { get; set; }

        private static bool newLine = true;
        private static Mutex mutex = new Mutex();

        static Log()
        {
            Debug = Information = Warning = Console.Out;
            Error = Console.Error;
        }

        public static void Lock()
        {
            mutex.WaitOne();
        }
        public static void Unlock()
        {
            mutex.ReleaseMutex();
        }

        public static void WriteLine(TextWriter log, ConsoleColor color, string format)
        {
            if (log == Console.Out || log == Console.Error)
            {
                Console.ForegroundColor = color;
                if (newLine)
                    ClearLine();
                newLine = true;
            }

            log.WriteLine(format);

            if (log == Console.Out)
                Console.ForegroundColor = DefaultColor;
        }
        public static void WriteLine(TextWriter log, ConsoleColor color, string format, params object[] args)
        {
            WriteLine(log, color, string.Format(format, args));
        }
        public static void WriteLine(TextWriter log, string format)
        {
            WriteLine(log, DefaultColor, format);
        }
        public static void WriteLine(TextWriter log, string format, params object[] args)
        {
            WriteLine(log, DefaultColor, format, args);
        }
        public static void WriteLine(TextWriter log)
        {
            if (log == Console.Out || log == Console.Error)
                newLine = true;

            log.WriteLine();
        }

        public static void Write(TextWriter log, ConsoleColor color, string format)
        {
            if (log == Console.Out || log == Console.Error)
            {
                Console.ForegroundColor = color;
                if (newLine)
                    ClearLine();
                newLine = false;
            }

            log.Write(format);

            if (log == Console.Out)
                Console.ForegroundColor = DefaultColor;
        }
        public static void Write(TextWriter log, ConsoleColor color, string format, params object[] args)
        {
            Write(log, color, string.Format(format, args));
        }
        public static void Write(TextWriter log, string format)
        {
            Write(log, DefaultColor, format);
        }
        public static void Write(TextWriter log, string format, params object[] args)
        {
            Write(log, DefaultColor, format, args);
        }

        private static void ClearLine()
        {
            Console.Write('\r');
            Console.Write(new string(' ', Console.WindowWidth - 1));
            Console.Write('\r');
        }
    }
}
